console.log('hello myPromise')
/**
 * @version 1.0.0 
 * MyPromise  主体思路 
 * 1.Promise 是一个构造函数，有三个状态：pending、fulfilled、rejected
 * 2.new Promise时，传入一个 executor 函数，该函数立即执行
 * 3.executor 函数接受两个参数，resolve 和 reject 两个函数
 * 4.默认状态是 pending
 * 5.Promise 的成功值保存在 success 里
 * 6.Promise 的失败值保存在 error 里
 * 7.Promise 的状态只能从 pending 变为 fulfilled，或者从 pending 变为 rejected，状态变化后不可改变
 * 8.Promise 的 then 方法接受两个参数，分别是成功回调 onFulfilled，失败的回调 onRejected
 * 9.执行 then 方法时，promise 状态成功，则执行 onFulfilled
 * 10.执行 then 方法时，promise 状态失败，则执行 onRejected
 * 11.then 如果抛出异常，那么异常函数中返回的值就会做为参数传递给下一个 then，触发下一个 then 的 onFulfilled 回调（见test1.js示例）
 * 12.onResolvedCallbacks 队列，用于存放成功的回调，调用 resolve 方法时，依次执行该队列里的回调
 * 13.onRejectedCallbacks 队列，用于存放失败的回调，调用 reject 方法时，依次执行该队列里的回调
 * 14.链式调用实现，then 方法里返回一个新的 Promise 对象
*/

const PENDING ='pending';
const FULFILLED ='fulfilled';
const REJECTED ='rejected';

function MyPromise(executor) {
    let self = this

    this.state = PENDING;        // Promise 的状态
    this.success = undefined;    // 保存成功的值
    this.error = undefined;      // 保存失败的值
    this.onResolvedCallbacks = []// 存放成功回调的数组
    this.onRejectedCallbacks = []// 存放失败回调函数的数组

    // Promise 改变为成功状态，触发成功回调
    function resolve(args) {
        // 状态只能是 'pending' -->  'fulfilled' 或者 'pending' -->  'rejected' 
        if(self.state === PENDING) {
            self.success = args  // 存储成功的值
            self.state = FULFILLED // 状态改为 fulfilled
            self.onResolvedCallbacks.forEach(task => task()); // 依次触发成功队列中的回调
        }
    }

    // Promise 改变为失败状态，触发失败回调
    function reject(args) {
        // 状态只能是 'pending' -->  'fulfilled' 或者 'pending' -->  'rejected' 
        if(self.state === PENDING) {
            self.error = args  // 存储失败的值
            self.state = REJECTED // 状态改为 rejected
            self.onRejectedCallbacks.forEach(task => task())  // 依次触发失败队列中的回调
        }
    }

    try {
        executor(resolve, reject)  // 执行函数
    } catch (error) {
        reject(error)   // 调用 reject
    }
}

// then 方法，原型方法
MyPromise.prototype.then = function(onFulfilled, onRejected) {
    let self = this

    // 生成一个新的 promise 对象
    let promise2 = new MyPromise(function (resolve, reject) {
        if(self.state === FULFILLED) {
            // 触发成功回调 onFulfilled
            let returnValue = onFulfilled(self.success)
            resolve(returnValue)
        }
        if(self.state === REJECTED) {
            // 触发失败回调 onRejected
            let returnValue = onRejected(self.error)
            resolve(returnValue)
        }
        if(self.state === PENDING) {
            // 将成功回调添加到 onResolvedCallbacks 数组中（收集依赖）
            self.onResolvedCallbacks.push(function () {
                let returnValue = onFulfilled(self.success)
                resolve(returnValue)
            })
            // 将失败回调添加到 onRejectedCallbacks 数组中（收集依赖）
            self.onRejectedCallbacks.push(function () {
                let returnValue = onRejected(self.error)
                resolve(returnValue)
            })
        }
    })

    // 返回 promise2 对象，实现链式调用
    return promise2
}

// catch   方法，原型方法
MyPromise.prototype.catch = function(callback) {
    let self = this
    return self.then(null, callback)
}

// all 方法，静态方法
MyPromise.all = function(promises) {
    return new MyPromise(function (resolve, reject) {
        let count = 0
        let result = []
        function processUpdate (key, value) {
            result[key] = value
            if(++count === promises.length) {
                resolve(result)
            }
        }
        for (let i = 0; i < promises.length; i++) {
            let promise = promises[i];
            if(promise && promise.then && typeof promise.then === 'function') {
                // promise 对象
                promise.then.call(promise, function(res) {
                    processUpdate(i, res)
                }, reject)
            } else {
                // 处理基本类型参数
                processUpdate(i, promise)
            }
        }
    })
}

module.exports = MyPromise